<template>
  <div class="step3-container">
    <!-- 匹配成功数据表格 -->
    <Divider> {{ t('匹配成功数据') }} </Divider>
    <div class="table-section">
      <div class="table-title">
        <!-- <h3>{{ t('匹配成功') }}</h3> -->
      </div>
      <BasicTable
        ref="successTableRef"
        :columns="successColumns"
        :dataSource="successList"
        :rowKey="'matchRowId'"
        :autoCreateKey="false"
        :canResize="false"
        :showTableSetting="false"
        :useSearchForm="false"
        :showIndexColumn="false"
        :bordered="true"
        size="small"
        :pagination="false"
      />
    </div>
    <!-- 不匹配数据表格 -->
    <Divider> {{ t('异常数据') }} </Divider>
    <div class="lg:flex">
      <!-- 不匹配存货清单 -->
      <div class="enter-y !mr-4 lg:w-5/12">
        <div class="table-title">
          <h3>{{ t('存货清单') }}</h3>
        </div>
        <BasicTable
          ref="inventoryTableRef"
          :columns="inventoryColumns"
          :dataSource="mismatchInventoryList"
          :rowKey="'rowNum'"
          :autoCreateKey="false"
          :canResize="false"
          :showTableSetting="false"
          :useSearchForm="false"
          :showIndexColumn="false"
          :bordered="true"
          size="small"
          :pagination="false"
          :rowSelection="inventoryRowSelection"
          :minHeight="100"
          :scroll="{ y: 260 }"
        />
      </div>

      <!-- 手动匹配按钮 -->
      <div class="enter-y lg:w-1/12 flex items-center justify-center">
        <Button type="primary" @click="handleManualMatch" :disabled="!canMatch">
          {{ t('手动匹配') }}
        </Button>
      </div>

      <!-- 不匹配发票清单 -->
      <div class="enter-y lg:w-6/12">
        <div class="table-title">
          <h3>{{ t('发票清单') }}</h3>
        </div>
        <BasicTable
          ref="invoiceTableRef"
          :columns="invoiceColumns"
          :dataSource="mismatchInvoiceList"
          :rowKey="'rowNum_invoiceNum'"
          :autoCreateKey="false"
          :canResize="false"
          :showTableSetting="false"
          :useSearchForm="false"
          :showIndexColumn="false"
          :bordered="true"
          size="small"
          :pagination="false"
          :rowSelection="invoiceRowSelection"
          :minHeight="100"
          :scroll="{ y: 260 }"
        />
      </div>
    </div>

  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, h, watch, nextTick, inject } from 'vue';
  import { BasicTable } from '/@/components/Table';
  import { Button, InputNumber, message, Divider } from 'ant-design-vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import type { InvoiceApi } from '../useInvoiceApi';

  const { t } = useI18n();
  const invoiceApiRef = inject<import('vue').Ref<InvoiceApi>>('invoiceApi')!;

  interface InvoiceParams {
    djno: string;
    pkCorp: string;
  }
  const props = defineProps({
    invoiceParams: {
      type: Object as () => InvoiceParams,
      default: () => ({
        djno: '',
        pkCorp: '',
      }),
    },
  });

  // 定义 emits
  const emit = defineEmits(['prev', 'next']);

  // 表格引用
  const successTableRef = ref();
  const inventoryTableRef = ref();
  const invoiceTableRef = ref();

  // 匹配结果数据源
  const successList = ref<any[]>([]);
  const mismatchInventoryList = ref<any[]>([]);
  const mismatchInvoiceList = ref<any[]>([]);
  // 发票原始快照（用于取消匹配时恢复被完全匹配后移除的发票行）
  const invoiceSnapshotMap = new Map<string | number, any>();

  // 选中的行
  const selectedInventoryKeys = ref<number[]>([]);
  const selectedInvoiceKeys = ref<Array<string | number>>([]);

  // 匹配成功表格列定义
  const successColumns = [
    {
      title: t('序号'),
      dataIndex: 'rowNum',
      width: 80,
      align: 'center',
    },
    {
      title: t('存货编码'),
      dataIndex: 'cinvcode',
      width: 120,
    },
    {
      title: t('货物或应税劳务名称'),
      dataIndex: 'cinvname',
      width: 200,
    },
    {
      title: t('规格型号'),
      dataIndex: 'cinvspec',
      width: 120,
    },
    {
      title: t('单位'),
      dataIndex: 'measname',
      width: 80,
      align: 'center',
    },
    {
      title: t('数量'),
      dataIndex: 'iqty',
      width: 100,
      align: 'right',
    },
    {
      title: t('无税单价'),
      dataIndex: 'nprice',
      width: 120,
      align: 'right',
    },
    {
      title: t('无税金额'),
      dataIndex: 'nmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('税率'),
      dataIndex: 'nictaxrate',
      width: 80,
      align: 'center',
    },
    {
      title: t('税额'),
      dataIndex: 'ntaxmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('含税金额'),
      dataIndex: 'noritaxmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('匹配发票'),
      dataIndex: 'matchInvoices',
      width: 150,
      customRender: ({ record }) => {
        const list = Array.isArray(record.matchInvoices) ? record.matchInvoices : [];
        return h(
          'div',
          {},
          list.map((item: any) =>
            h(
              'div',
              { style: 'line-height: 22px;' },
              `${item.invoiceNum || ''} - ${Number(item.matchMny || 0).toFixed(2)}`,
            ),
          ),
        );
      },
    },
    {
      title: t('操作'),
      dataIndex: 'action',
      width: 100,
      align: 'center',
      customRender: ({ record }) =>
        h(
          Button,
          {
            type: 'link',
            size: 'small',
            disabled: record?.editable !== true,
            onClick: () => {
              if (record?.editable !== true) return;
              handleUnmatch(record);
            },
          },
          () => t('取消匹配'),
        ),
    },
  ];

  // 存货清单表格列定义
  const inventoryColumns = [
    {
      title: t('序号'),
      dataIndex: 'rowNum',
      width: 80,
      align: 'center',
    },
    {
      title: t('存货编码'),
      dataIndex: 'cinvcode',
      width: 120,
    },
    {
      title: t('货物或应税劳务名称'),
      dataIndex: 'cinvname',
      width: 200,
    },
    {
      title: t('规格型号'),
      dataIndex: 'cinvspec',
      width: 120,
    },
    {
      title: t('单位'),
      dataIndex: 'measname',
      width: 80,
      align: 'center',
    },
    {
      title: t('数量'),
      dataIndex: 'iqty',
      width: 100,
      align: 'right',
    },
    {
      title: t('无税单价'),
      dataIndex: 'nprice',
      width: 120,
      align: 'right',
    },
    {
      title: t('无税金额'),
      dataIndex: 'nmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('税率'),
      dataIndex: 'nictaxrate',
      width: 80,
      align: 'center',
    },
    {
      title: t('税额'),
      dataIndex: 'noritaxmny',
      width: 80,
      align: 'center',
    },
    {
      title: t('含税金额'),
      dataIndex: 'ntaxmny',
      width: 120,
      align: 'right',
    },
  ];

  // 发票清单表格列定义
  const invoiceColumns = [
    {
      title: t('行号'),
      dataIndex: 'rowNum',
      width: 80,
      align: 'center',
    },
    {
      title: t('发票号'),
      dataIndex: 'invoiceNum',
      width: 120,
    },
    {
      title: t('货物或应税劳务名称'),
      dataIndex: 'cinvname',
      width: 200,
    },
    {
      title: t('规格型号'),
      dataIndex: 'cinvspecAndCinvtype',
      width: 120,
    },
    {
      title: t('单位'),
      dataIndex: 'measname',
      width: 80,
      align: 'center',
    },
    {
      title: t('数量'),
      dataIndex: 'iqty',
      width: 100,
      align: 'right',
    },
    {
      title: t('无税单价'),
      dataIndex: 'nprice',
      width: 120,
      align: 'right',
    },
    {
      title: t('无税金额'),
      dataIndex: 'nmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('税率'),
      dataIndex: 'nictaxrate',
      width: 80,
      align: 'center',
    },
    {
      title: t('税额'),
      dataIndex: 'ntaxmny',
      width: 120,
      align: 'right',
    },
    {
      title: t('含税金额'),
      dataIndex: 'noritaxmny',
      width: 120,
      align: 'right',
    },
    // 可以编辑的 匹配金额
    {
      title: t('匹配金额'),
      dataIndex: 'matchMny',
      width: 120,
      align: 'right',
      fixed: 'right',
      customRender: ({ record }) =>
        h(InputNumber as any, {
          value: record.matchMny,
          min: 0,
          max: Number(record.nmny) || 0,
          precision: 2,
          size: 'small',
          style: 'width: 100px',
          onChange: (val: number) => {
            const max = Number(record.nmny) || 0;
            record.matchMny = Math.min(Number(val || 0), max);
          },
        }),
    },
  ];

  // 存货清单行选择配置
  const inventoryRowSelection = {
    selectedRowKeys: selectedInventoryKeys,
    onChange: (selectedRowKeys: number[]) => {
      selectedInventoryKeys.value = selectedRowKeys;
    },
    type: 'radio',
    fixed: true,
  };

  // 发票清单行选择配置
  const invoiceRowSelection = {
    selectedRowKeys: selectedInvoiceKeys,
    onChange: (selectedRowKeys: number[]) => {
      selectedInvoiceKeys.value = selectedRowKeys;
    },
    type: 'checkbox',
    fixed: true,
  };

  // 是否可以匹配
  const canMatch = computed(
    () => selectedInventoryKeys.value.length > 0 && selectedInvoiceKeys.value.length > 0,
  );

  // 手动匹配
  const handleManualMatch = () => {
    if (!canMatch.value) return;
    const invKey = selectedInventoryKeys.value[0];
    const inventoryRecord = mismatchInventoryList.value.find((i) => i.rowNum === invKey);
    if (!inventoryRecord) return;
    const invAmount = Number(inventoryRecord.nmny) || 0;

    const pickedInvoices = mismatchInvoiceList.value.filter(
      (r) => selectedInvoiceKeys.value.includes(r.rowNum_invoiceNum),
    );
    if (!pickedInvoices.length) return;

    const totalMatch = pickedInvoices.reduce((sum, r) => sum + (Number(r.matchMny) || 0), 0);
    console.log('totalMatch', totalMatch);
    if (Math.abs(totalMatch - invAmount) >= 0.0001) {
      message.warning(t('匹配金额需要与存货无税金额一致'));
      return;
    }

    // 不再使用旧的 payload 结构，改为保存三类列表整体到暂存接口

    const successItem = {
      ...inventoryRecord,
      matchRowId: inventoryRecord.rowNum,
      // 可以编辑的标识
      editable: true,
      matchInvoices: pickedInvoices.map((p) => ({
        invoiceNum: p.invoiceNum,
        rowNum: p.rowNum,
        rowNum_invoiceNum: `${p.invoiceNum || ''}_${p.rowNum}`,
        matchMny: Number(p.matchMny) || 0,
      })),
    };
    successList.value.push(successItem);

    mismatchInventoryList.value = mismatchInventoryList.value.filter((i) => i.rowNum !== invKey);

    const usedKeys = new Set(pickedInvoices.map((p) => p.rowNum_invoiceNum));
    mismatchInvoiceList.value = mismatchInvoiceList.value
      .map((item) => {
        if (!usedKeys.has(item.rowNum_invoiceNum)) return item;
        const left = (Number(item.nmny) || 0) - (Number(item.matchMny) || 0);
        if (left <= 0.0001) {
          return null as any;
        }
        return {
          ...item,
          nmny: Number(left.toFixed(2)),
          matchMny: null,
        };
      })
      .filter(Boolean);

    // 记录发票原始快照，便于取消匹配时恢复（若未记录则保存一次）
    pickedInvoices.forEach((p) => {
      if (!invoiceSnapshotMap.has(p.rowNum_invoiceNum)) {
        invoiceSnapshotMap.set(p.rowNum_invoiceNum, JSON.parse(JSON.stringify(p)));
      }
    });

    selectedInventoryKeys.value = [];
    selectedInvoiceKeys.value = [];

    // 暂存当前整体匹配状态
    const tempPayload = {
      pkCorp: props.invoiceParams.pkCorp,
      djno: props.invoiceParams.djno,
      successList: successList.value,
      mismatchInvoiceList: mismatchInvoiceList.value,
      mismatchInventoryList: mismatchInventoryList.value,
    } as any;
    invoiceApiRef.value.tempSave(tempPayload)
      .then(() => {
        message.success(t('已暂存当前匹配结果'));
      })
      .catch((e) => {
        console.error('暂存匹配结果失败', e);
        message.error(t('暂存匹配结果失败'));
      });
  };

  // 取消匹配
  const handleUnmatch = (record: any) => {
    try {
      // 从成功列表移除
      successList.value = successList.value.filter((r) => r.matchRowId !== record.matchRowId);

      // 还原存货到不匹配列表
      const restoreInv = { ...record };
      delete (restoreInv as any).matchInvoices;
      mismatchInventoryList.value.push(restoreInv);

      // 逐条还原发票无税金额
      const list = Array.isArray(record.matchInvoices) ? record.matchInvoices : [];
      list.forEach((mi: any) => {
        const key = mi.rowNum_invoiceNum || `${mi.invoiceNum || ''}_${mi.rowNum}`;
        const matchMny = Number(mi.matchMny) || 0;
        const existed = mismatchInvoiceList.value.find((r) => r.rowNum_invoiceNum === key);
        if (existed) {
          const newNmny = Number(Number(existed.nmny || 0) + matchMny);
          existed.nmny = Number(newNmny.toFixed(2));
          existed.matchMny = existed.nmny;
        } else {
          const snap = invoiceSnapshotMap.get(key);
          if (snap) {
            const readd = {
              ...snap,
              nmny: Number(matchMny.toFixed(2)),
              matchMny: Number(matchMny.toFixed(2)),
            };
            mismatchInvoiceList.value.push(readd);
          } else {
            // 无快照则以最小字段补充一条记录
            mismatchInvoiceList.value.push({
              rowNum: mi.rowNum,
              invoiceNum: mi.invoiceNum,
              rowNum_invoiceNum: key,
              nmny: Number(matchMny.toFixed(2)),
              matchMny: Number(matchMny.toFixed(2)),
            } as any);
          }
        }
      });

      // 清空选择
      selectedInventoryKeys.value = [];
      selectedInvoiceKeys.value = [];
      message.success(t('已取消匹配，并恢复至未匹配列表'));

      // 暂存当前整体匹配状态
      const tempPayload = {
        pkCorp: props.invoiceParams.pkCorp,
        djno: props.invoiceParams.djno,
        successList: successList.value,
        mismatchInvoiceList: mismatchInvoiceList.value,
        mismatchInventoryList: mismatchInventoryList.value,
      } as any;
      invoiceApiRef.value.tempSave(tempPayload).catch((e) => {
        console.error('取消匹配后暂存失败', e);
      });
    } catch (e) {
      console.error('取消匹配失败', e);
      message.error(t('取消匹配失败'));
    }
  };

  // 上一步
  const handlePrev = () => {
    emit('prev');
  };

  // 拉取匹配结果
  const fetchMatchResults = async () => {
    if (!props.invoiceParams?.djno || !props.invoiceParams?.pkCorp) return;
    try {
      const res: any = await invoiceApiRef.value.execMatch({
        djno: props.invoiceParams.djno,
        pkCorp: props.invoiceParams.pkCorp,
      });
      successList.value = res?.successList || res?.data?.successList || [];
      mismatchInvoiceList.value = res?.mismatchInvoiceList || res?.data?.mismatchInvoiceList || [];
      mismatchInventoryList.value =
        res?.mismatchInventoryList || res?.data?.mismatchInventoryList || [];
      // 初始化发票匹配金额为无税金额
      mismatchInvoiceList.value = mismatchInvoiceList.value.map((item) => ({
        ...item,
        // 将行键重置为 发票号 + 行号 的唯一拼接
        rowNum_invoiceNum: `${item.invoiceNum || ''}_${item.rowNum}`,
        matchMny: Number(item.nmny) || 0,
      }));
      // 构建发票原始快照（用于取消匹配恢复）
      invoiceSnapshotMap.clear();
      mismatchInvoiceList.value.forEach((item) => {
        invoiceSnapshotMap.set(item.rowNum_invoiceNum, JSON.parse(JSON.stringify(item)));
      });
      await nextTick();
    } catch (e) {
      console.error('获取匹配结果失败', e);
    }
  };

  // 当参数变化时刷新
  watch(
    () => ({ ...props.invoiceParams }),
    async () => {
      await fetchMatchResults();
    },
    { immediate: true },
  );

  // 仅在进入本步骤或参数变化时拉取数据（由 watch immediate 触发）

  // 下一步
  const handleNext = async () => {
    const payload = {
      pkCorp: props.invoiceParams.pkCorp,
      djno: props.invoiceParams.djno,
      successList: successList.value,
      mismatchInvoiceList: mismatchInvoiceList.value,
      mismatchInventoryList: mismatchInventoryList.value,
    } as any;
    try {
      await invoiceApiRef.value.submit(payload);
      message.success(t('匹配已提交'));
      // 提交后，成功列表不允许再操作取消匹配
      successList.value = successList.value.map((item) => ({ ...item, editable: false }));
    } catch (e) {
      console.error('提交匹配结果失败', e);
      message.error(t('提交匹配结果失败'));
    }
  };

  // 暴露方法，供父组件触发
  defineExpose({ reload: fetchMatchResults, prev: handlePrev, next: handleNext });
</script>
